#include <unicode/brkiter.h>
#include <unicode/unistr.h>
#include<iostream>
#include<memory>

// std::string GetAbstractImproved(const std::string& content, const std::string& key) {
//     // 初始化ICU环境
//     UErrorCode status = U_ZERO_ERROR;
//     icu::Locale locale("zh", "CN"); // 中文场景
    
//     // 创建句子边界迭代器
//     icu::BreakIterator* bi = icu::BreakIterator::createSentenceInstance(
//         locale, status);
    
//     icu::UnicodeString uContent = icu::UnicodeString::fromUTF8(content);
//     bi->setText(uContent);
    
//     // 查找关键词位置
//     int32_t pos = uContent.indexOf(icu::UnicodeString::fromUTF8(key));
//     if (pos == -1) return "关键词未找到";
    
//     // 定位句子边界
//     int32_t start = bi->preceding(pos + 1);
//     int32_t end = bi->next();
    
//     // 动态扩展上下文
//     int32_t finalStart = std::max(0, start);
//     int32_t finalEnd = std::min(uContent.length(),end);
    
//     // 提取摘要
//     icu::UnicodeString abstract = uContent.tempSubStringBetween(finalStart, finalEnd);
//     std::string result;
//     abstract.toUTF8String(result);
    
//     delete bi;
//     return result + "...";
// }

// std::string  GetAbstractImproved(const std::string& content,const std::string & key)
// {
//     //0.初始化错误状态码
//     UErrorCode status = U_ZERO_ERROR;

//     //1.初始化ICU环境
//     icu::Locale locale("zh", "CN");//英文优先，中文次之

//     //2.拿到句子边界分析器
//     icu::BreakIterator* bi = icu::BreakIterator::createSentenceInstance(locale,status);
//     // std::unique_ptr<icu::BreakIterator> bi(rawbi);

//     icu::UnicodeString uContent = icu::UnicodeString::fromUTF8(content);
//     bi->setText(uContent);
//     //3.找到key第一次出现的位置
//     int pos = content.find(key);

//     if(pos == std::string::npos)//理论上不可能出现，没有查找到关键词在文档中的位置
//         return "None1";
//     //4.向前查找最近的边界
//     std::cout << pos << std::endl;
//     int32_t start = bi->preceding(pos+1);
//     std::cout << start << "\n";
//     if(start == icu::BreakIterator::DONE)
//         start = 0;
//     //5.向后查找下一个边界
//     int32_t end = bi->next();//跳过1个边界
//     std::cout << end << "\n";
//     if(end == icu::BreakIterator::DONE)
//         end = uContent.length()-1;
//         // 提取摘要
//     icu::UnicodeString abstract = uContent.tempSubStringBetween(start,end);
//     std::string result;
//     abstract.toUTF8String(result);
    
//     return result;
// }


void debugBreakpoints(BreakIterator* bi, const UnicodeString& text);

std::string GetAbstractImproved(std::string &content, const std::string &key)
{
    // 0. 初始化错误状态码
    UErrorCode status = U_ZERO_ERROR;

    // 1. 初始化ICU环境
    icu::Locale locale("en_US");

    // 2. 拿到句子边界分析器
    std::unique_ptr<icu::BreakIterator> bi(icu::BreakIterator::createSentenceInstance(locale, status));
    if (U_FAILURE(status))
    {
        return "Error creating BreakIterator";
    }

    std::unique_ptr<icu::BreakIterator> bw(icu::BreakIterator::createWordInstance(locale, status));

    icu::UnicodeString uContent = icu::UnicodeString::fromUTF8(content);
    icu::UnicodeString uContent_lower(uContent);
    uContent_lower.toLower(locale);

    bi->setText(uContent);
    bw->setText(uContent);

    // 3. 找到key第一次出现的位置
    int32_t pos = uContent_lower.indexOf(icu::UnicodeString::fromUTF8(key));
    if (pos == std::string::npos)
    { // 理论上不可能出现，没有查找到关键词在文档中的位置
        return "None1";
    }


    // 4. 向前查找最近的边界
    int32_t start = bi->preceding(pos + 1); // 直接使用pos作为参数
    if (start == icu::BreakIterator::DONE)
    {
        start = 0;
    }

    // 5. 向后查找下一个边界
    int32_t end = bi->next(2); // 获取下一个边界
    if (end == icu::BreakIterator::DONE)
    {
        end = uContent.length();
    }

    end = bw->following(end);
    if (end != icu::BreakIterator::DONE)
    {
        end = bw->next();
    }

    if(end <= start)
        return "None2";
    // 提取摘要
    icu::UnicodeString abstract = uContent.tempSubStringBetween(start, end);
    std::string result;
    abstract.toUTF8String(result);

    result += "...";

    return result;
}
// void debugBreakpoints(BreakIterator* bi, const UnicodeString& text) {
//     int32_t pos = bi->first();
//     while (pos != BreakIterator::DONE) {
//         // 获取上下文片段
//         UnicodeString snippet;
//         text.extract(pos, 5, snippet); // 取断点后5个字符
//         std::string s;
//         snippet.toUTF8String(s);
//         std::cout << "Break@" << pos << ": [" << s << "]" << std::endl;
        
//         pos = bi->next();
//     }
// }
int main()
{
    std::string s = R"(The sun sets beautifully over the horizon.The sun sets beautifully over the horizon.    Yes,od,id.好的，用户之前询问了如何在C++中使用ICU库来改进生成摘要的方法，现在他们想知道在CentOS 7上如何安装ICU库。我需要详细说明安装步骤，同时考虑到CentOS 7的软件包管理工具主要是yum，但可能版本较旧，所以可能需要源码编译。首先，我应该检查用户是否有root权限，因为安装系统包通常需要sudo。常见的安装方法有两种：使用yum安装预编译的包，或者从源码编译安装以获得最新版本。CentOS 7的默认仓库可能提供ICU，但版本可能较低，所以需要确认版本是否满足需求。如果用户需要较新版本，源码编译是更好的选择。其次，步骤需要清晰，分点列出。使用yum安装的话，可以列出相关包名，比如libicu和开发包libicu-devel。然后说明如何验证安装，比如检查头文件和库文件的位置。对于源码安装，需要指导用户下载最新源码，解压，然后执行标准的configure、make、make install流程。需要注意依赖项的安装，比如可能需要的开发工具链（gcc、make等），以及可能的配置选项，比如安装路径。此外，要提醒用户设置环境变量，如LD_LIBRARY_PATH，或者更新动态库缓存)";

    std::cout << GetAbstractImproved(s,"yes") << std::endl;

}
// #include<unordered_map>
// #include<vector>
// #include<algorithm>

// using namespace std;

// int main()
// {
//     vector<int> arr = {1,4,2,3,6,7,2,9,11,32,21,78};
//     unordered_map<int,vector<int>> mp;
//     mp[0] = arr;

//     return 0;
// }
// #include<iostream>
// #include<memory>
// #include<boost/filesystem.hpp>

// #include<vector>
// const std::string root_path = "./testfilesystem";

// int main()
// {
//     namespace fs = boost::filesystem;
//     fs::path root(root_path);
//     if(!fs::exists(root))
//         std::cerr << "root is not exists..." << "\n";
    
//     std::vector<std::string>  res;
//     fs::recursive_directory_iterator end;
//     for(fs::recursive_directory_iterator begin(root);begin != end;++begin)
//     {
//         if(!fs::is_regular(*begin))
//             continue;
//         if(fs::extension(*begin) != ".c")//后缀必须为.c
//             continue;
        
//         res.emplace_back(begin->path().string());
//     }

//     for(auto& s:res)
//         std::cout << s << "\n";
    
//     return 0;
// }
// int main()
// {
//     std::unique_ptr<int> ptr = std::make_unique<int>();
//     return 0;
// }